//
//  ResourceLoaderDelegate.m
//  Player
//
//  Created by Burn on 2019/7/5.
//  Copyright © 2019 menksoft. All rights reserved.
//

#import "ResourceLoaderDelegate.h"
#import "RemotePlayerDownloader.h"
#import "RemotePlayerFileManager.h"
#import "NSURL+StreamingURL.h"
@interface ResourceLoaderDelegate ()<RemotePlayerDownloaderDelegate>

@property(strong,nonatomic) RemotePlayerDownloader *loader;

@property(assign,nonatomic) NSInteger currentLength;

@property(strong,nonatomic) NSMutableArray<AVAssetResourceLoadingRequest *> *loadingRequests;


@end

@implementation ResourceLoaderDelegate

- (RemotePlayerDownloader *)loader{
    if (!_loader) {
        _loader = [[RemotePlayerDownloader alloc]init];
        _loader.delegate = self;
    }
    return _loader;
}

- (NSMutableArray *)loadingRequests{
    if (!_loadingRequests) {
        _loadingRequests = [NSMutableArray array];
    }
    return _loadingRequests;
}

#pragma mark - AVAssetResourceLoaderDelegate
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest{
    // !!!: 需要播放一段资源时会抛出一个请求给这对象

    NSURL *url = [loadingRequest.request.URL compenst];
    
    //  保存请求
    [self.loadingRequests addObject:loadingRequest];
    
    //  如果没有URL不处理
    if (!url) { DLOG(@"请求的URL是空的 Return NO"); return NO; }
    
    //  如果已经下载好了
    if ([[RemotePlayerFileManager shared]cacheFileExists:url]) {
        [self handleLoaderRequesyWith:loadingRequest];
        return YES;
    }
    
    //  如果offset 为空
//    if (!self.loadingRequests.firstObject.dataRequest.currentOffset) {DLOG(@"currentOffset是空的 Return NO"); return NO;}
    
    //  如果是新请求
    if (self.loader.totalSize == 0) {
        [self.loader downloadWithURL:url offset:self.loadingRequests.firstObject.dataRequest.currentOffset];
        return YES;
        DLOG(@"新的下载请求-新的下载");
    }
    
    //  如果下载的位置太远没法等待数据缓存,直接重新加载
    if (self.loader.offset + self.loader.totalSize < self.loadingRequests.firstObject.dataRequest.currentOffset) {
        [self.loader downloadWithURL:url offset:self.loadingRequests.firstObject.dataRequest.currentOffset];
        DLOG(@"请求的数据位置太靠后重新下载");
        return YES;
    }
    
    //  如果请求正好是当前下载的数据f范围内
    [self handleLoadingRequest];
    return YES;

}

//  取消请求-某一段请求
- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest{
    //  从数组中删除
    [self.loadingRequests removeObject:loadingRequest];
}


#pragma mark - 这段请求数据已经下载好了的请款下
- (void)handleLoaderRequesyWith:(AVAssetResourceLoadingRequest *)loadingRequest{
    
    loadingRequest.contentInformationRequest.contentLength = [[RemotePlayerFileManager shared]cacheFileSizeWith:loadingRequest.request.URL];
    loadingRequest.contentInformationRequest.contentType = [[RemotePlayerFileManager shared]contentTypeWith:loadingRequest.request.URL];
    
    // Before you finish loading an AVAssetResourceLoadingRequest, if its contentInformationRequest is not nil, you should set the value of this property to YES if you support random access to arbitrary ranges of bytes of the resource. If you do not set this property to YES for resources that must be loaded incrementally, loading of the resource may fail. Such resources include anything that contains media data.
    [loadingRequest.contentInformationRequest setByteRangeAccessSupported:YES]; // 上面的意思大概支持任意字节区间防范资源
    NSError *error;
    NSData *data = [NSData dataWithContentsOfFile:[[RemotePlayerFileManager shared] cacheFilePathWith:loadingRequest.request.URL] options:NSDataReadingMappedIfSafe error:&error];
    
    if (error) {
        DLOG(@"从缓存中取数据出现错误");
        return;
    }
    
    //  获取本次请求的数据
    NSInteger requestOffset = loadingRequest.dataRequest.requestedOffset;   //  请求的起点
    NSInteger requestLength = loadingRequest.dataRequest.requestedLength;
    NSRange requestRange = NSMakeRange(requestOffset, requestLength);
    
    NSData *subData = [data subdataWithRange:requestRange];
    
    //  响应数据-或者抛出数据
    [loadingRequest.dataRequest respondWithData:subData];
    //  结束本次请求
    [loadingRequest finishLoading];
}


#pragma mark - 处理正在下载数据的请求
- (void)handleLoadingRequest{
    
    //  获取请求
    AVAssetResourceLoadingRequest *loadingRequest = [self.loadingRequests firstObject];
    if (!loadingRequest) { DLOG(@"正在下载请求为空%@",loadingRequest); return;}
    if (!loadingRequest.request.URL) {DLOG(@"正在下载处理请求URL为空%@",loadingRequest.request.URL); return;}
    //  设置请求相关的数据
    [self setLoadingRequestInformation:loadingRequest.contentInformationRequest];
    
    //  获取数据-先从temp中获取-获取不到试试cache
    NSError *error;
    NSData *data = [NSData dataWithContentsOfFile:[[RemotePlayerFileManager shared] tempFilePathWith:loadingRequest.request.URL] options:NSDataReadingMappedAlways error:&error];
    if (error || data == nil || !data) {
        data = [NSData dataWithContentsOfFile:[[RemotePlayerFileManager shared] cacheFilePathWith:loadingRequest.request.URL] options:NSDataReadingMappedAlways error:&error];
        if (error || data == nil || !data){
            return DLOG(@"获取到的数据错误");
        }
    }
    
    
    NSInteger requestOffset = loadingRequest.dataRequest.currentOffset;
    NSInteger requestLength = loadingRequest.dataRequest.requestedLength;
    
    NSInteger responsOffset = requestOffset - self.loader.offset;   //  responseOffset是相对下载数据计算
    NSInteger responsLength = MIN((self.loader.offset + data.length ) - requestOffset, requestLength);
    
    if (responsOffset > data.length || responsLength < 0) {
        [self.loader cancelAndClean];
        [self.loader downloadWithURL:loadingRequest.request.URL offset:responsOffset];
        return;
    }
    
    NSRange range = NSMakeRange(responsOffset, responsLength);
    DLOG(@"range = %ld-----%ld-----%ld",range.location,range.length,self.loadingRequests.count);
    NSData *subDada = [data subdataWithRange:range];
    if (!subDada) {DLOG(@"subData错误"); return;}
    self.currentLength += responsLength;
    [loadingRequest.dataRequest respondWithData:subDada];
    
    //  如果请求数据已经全部返回
    if (requestLength <= self.currentLength) {
        [_loadingRequests removeObject:loadingRequest];
        [loadingRequest finishLoading];
        DLOG(@"本次请求返回完毕");
        self.currentLength = 0;
    }
    
    
    
}
#pragma mark - 设置请求相关的数据
- (void)setLoadingRequestInformation:(AVAssetResourceLoadingContentInformationRequest *)informationRequest{
    informationRequest.contentType = self.loader.MIMEType;
    [informationRequest setByteRangeAccessSupported:YES];
    informationRequest.contentLength = self.loader.totalSize;
}


#pragma mark - RemotePlayerDownloaderDelegate
- (void)downLoading {
    [self handleLoadingRequest];
}

- (void)taskError_999:(nonnull NSURL *)url offset:(NSInteger)offset {
    
}


- (void)dealloc{
    
}
@end
